﻿
Imports std
Imports runrroom

Public Class lrclient_t
    Private talkpool As fixpoint_talkpool_t = Nothing

    Private Function talkaction(Of T) _
                               (ByVal resulthandle As _do(Of vector(Of pair(Of String, String)), T, Boolean), _
                                ByRef obj As T, _
                                ByVal ParamArray parameters() As String) As Boolean
        assert(Not resulthandle Is Nothing)
        Dim talk As tcpTalk = Nothing
        If talkpool.getfree(talk) Then
            Dim rtn As Boolean = False
            talk.sendData.clear()
            If nettransDataInserter.keyvaluepair(talk.sendData, parameters) Then
                If talk.talk() Then
                    Dim ps As vector(Of pair(Of String, String)) = Nothing
                    If nettransDataParser.keyvaluepair(talk.receiveData(), ps) AndAlso Not ps Is Nothing Then
                        rtn = resulthandle(ps, obj)
                    Else
                        raiseError("cannot parse lrserver response data to keyvalue pairs.", _
                                   errorHandle.errorType.exclamation)
                        rtn = False
                    End If
                Else
                    raiseError("cannot talk with lrserver " + talkpool.hostport(), errorHandle.errorType.warning)
                    rtn = False
                End If
            Else
                raiseError("cannot prepare keyvalue pair for run action.", errorHandle.errorType.exclamation)
                rtn = True
            End If
            If Not talkpool.release() Then
                raiseError("cannot release tcptalk to talkpool.", errorHandle.errorType.exclamation)
                rtn = False
            End If

            Return rtn
        Else
            raiseError("do not have free talk instance, " + _
                       "the threadcount of rrserver.tcpServer2 is not consistant with connectionCount.", _
                       errorHandle.errorType.warning)
            Return False
        End If
    End Function

    Public Function run(ByVal id As String, ByVal cmd As String) As Boolean
        Dim resulthandle As _do(Of vector(Of pair(Of String, String)), Object, Boolean) = _
            Function(ByRef ps As vector(Of pair(Of String, String)), ByRef __NOT_IN_USE__ As Object) As Boolean
                For i As Int64 = 0 To ps.size() - 1
                    If matchProtocol(ps(i), protocols.result) Then
                        If matchResult(ps(i), protocols.results.success) Then
                            Return True
                        Else
                            Return False
                        End If
                        Exit For
                    End If
                Next
                raiseError("lrserver responses without result protocol.", errorHandle.errorType.exclamation)
                Return False
            End Function

        Return talkaction(resulthandle, Nothing, _
                          protocols.action, protocols.actions.run, _
                          protocols.command, cmd, _
                          protocols.jobid, id)
    End Function

    Public Function status(ByVal id As String, ByRef percentage As percentage_t) As Boolean
        Dim resulthandle As _do(Of vector(Of pair(Of String, String)), percentage_t, Boolean) = _
            Function(ByRef ps As vector(Of pair(Of String, String)), ByRef percent As percentage_t) As Boolean
                Dim suc As Boolean = False
                Dim perc As SByte = 0
                Dim foundperc As Boolean = False
                For i As Int64 = 0 To ps.size() - 1
                    If matchProtocol(ps(i), protocols.result) Then
                        If matchResult(ps(i), protocols.results.success) Then
                            suc = True
                        End If
                    ElseIf matchProtocol(ps(i), protocols.percentage) Then
                        Dim tmp As SByte = 0
                        If convertor.tosbyte(result(ps(i)), tmp) Then
                            foundperc = True
                            perc = tmp
                        End If
                    End If
                Next

                If suc AndAlso foundperc Then
                    percent = New percentage_t(perc)
                    Return True
                Else
                    Return False
                End If
            End Function

        Return talkaction(resulthandle, percentage, _
                          protocols.action, protocols.actions.status, _
                          protocols.jobid, id)
    End Function

    Public Sub New(ByVal machine As String)
        talkpool = New fixpoint_talkpool_t(machine, connection_const.port.localrun, _
                                           connection_const.distrrun_localrun.holdtime, _
                                           connection_const.distrrun_localrun.livetime, _
                                           connection_const.distrrun_localrun.connectionCount)
    End Sub
End Class

Public Module _lrclients
    Private _lrclients As map(Of String, lrclient_t) = Nothing

    Sub New()
        _lrclients = New map(Of String, lrclient_t)()
    End Sub

    Public Function lrclient(ByVal machine As String) As lrclient_t
        Dim it As map(Of String, lrclient_t).iterator = Nothing
        it = _lrclients.find(machine)
        If it = _lrclients.end() Then
            it = _lrclients.insert(machine, New lrclient_t(machine))
        End If
        Return (+it).second
    End Function
End Module